package com.lzx.mumianaicodegenerator.langgraph4j.tool;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.RuntimeUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.system.SystemUtil;
import com.lzx.mumianaicodegenerator.exception.BusinessException;
import com.lzx.mumianaicodegenerator.exception.ErrorCode;
import com.lzx.mumianaicodegenerator.langgraph4j.ImageCategoryEnum;
import com.lzx.mumianaicodegenerator.langgraph4j.ImageResource;
import com.lzx.mumianaicodegenerator.manager.CosManager;
import dev.langchain4j.agent.tool.P;
import dev.langchain4j.agent.tool.Tool;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.io.File;
import java.io.IOException;
import java.util.*;

@Slf4j
@Component
public class MermaidDiagramTool {

    @Resource
    private CosManager cosManager;
    // 本地 Chrome 浏览器可执行文件路径，根据实际情况修改，这里是 Windows 系统下的示例路径
    private static final String CHROME_EXECUTABLE_PATH = "C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe";

    @Tool("将 Mermaid 代码转换为架构图图片，用于展示系统结构和技术关系")
    public List<ImageResource> generateMermaidDiagram(@P("Mermaid 图表代码") String mermaidCode,
                                                      @P("架构图描述") String description) {
        if (StrUtil.isBlank(mermaidCode)) {
            return new ArrayList<>();
        }
        try {
            // 转换为SVG图片
            File diagramFile = convertMermaidToSvg(mermaidCode);
            // 上传到COS
            String keyName = String.format("/mermaid/%s/%s",
                    RandomUtil.randomString(5), diagramFile.getName());
            String cosUrl = cosManager.uploadFile(keyName, diagramFile);
            // 清理临时文件
            FileUtil.del(diagramFile);
            if (StrUtil.isNotBlank(cosUrl)) {
                return Collections.singletonList(ImageResource.builder()
                        .category(ImageCategoryEnum.ARCHITECTURE)
                        .description(description)
                        .url(cosUrl)
                        .build());
            }
        } catch (Exception e) {
            log.error("生成架构图失败: {}", e.getMessage(), e);
        }
        return new ArrayList<>();
    }

    private File convertMermaidToSvg(String mermaidCode) {
        // Define the path to the local Chrome browser
        String chromeExecutablePath = "C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe"; // Update this path if needed

        // Create temporary input file
        File tempInputFile = FileUtil.createTempFile("mermaid_input_", ".mmd", true);
        FileUtil.writeUtf8String(mermaidCode, tempInputFile);

        // Create temporary output file
        File tempOutputFile = FileUtil.createTempFile("mermaid_output_", ".svg", true);

        // Choose command based on the operating system
        String command = SystemUtil.getOsInfo().isWindows() ? "mmdc.cmd" : "mmdc";

        // Create a process builder and set the environment variable
        ProcessBuilder processBuilder = new ProcessBuilder();
        Map<String, String> environment = processBuilder.environment();
        environment.put("PUPPETEER_EXECUTABLE_PATH", chromeExecutablePath);

        // Construct the command to run
        String cmdLine = String.format("%s -i %s -o %s -b transparent",
                command,
                tempInputFile.getAbsolutePath(),
                tempOutputFile.getAbsolutePath()
        );

        // Start the process with the updated environment
        try {
            Process process = processBuilder.command(cmdLine.split(" ")).start();
            process.waitFor();  // Wait for the command to finish execution
        } catch (IOException | InterruptedException e) {
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "Mermaid CLI 执行失败: " + e.getMessage());
        }

        // Check if output file exists and is not empty
        if (!tempOutputFile.exists() || tempOutputFile.length() == 0) {
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "Mermaid CLI 执行失败");
        }

        // Clean up input file, keep output file for uploading
        FileUtil.del(tempInputFile);
        return tempOutputFile;
    }

}